package com.xinyue.ext.reader.dao;

import java.util.ArrayList;
import java.util.List;

import org.dom4j.Element;
import org.dom4j.Node;

import com.xinyue.ext.data.FinderData;
import com.xinyue.ext.exception.FinderException;
import com.xinyue.ext.reader.ParamHolder;
import com.xinyue.ext.util.StringUtil;

public class RelyProcess extends DaoContext{
	//私有构造器
	private RelyProcess() {
	}
	//内部类
	private static class SingletonHolder{
        private static RelyProcess instance = new RelyProcess();  
    }
	/**
	 * 获得对象实例
	 */
	public static RelyProcess getInstance(ParamHolder holder) {
		DaoContext.holder = holder;
		return SingletonHolder.instance;
	}
	
	/**
	 * 读取many和one标签数据
	 * param entity entity标签
	 */
	@SuppressWarnings("unchecked")
	@Override
	public void read(Element entity) throws FinderException {
		List<Element> many = entity.elements(many_);
		List<Element> one = entity.elements(one_);
		
		List<FinderData> rely = new ArrayList<FinderData>();
		
		relyRead(many, rely, many_);
		relyRead(one, rely, one_);
		
		if(rely.size() > 0) {
			holder.getEntity().getDao().setRely(rely);
		}
	}
	
	/**
	 * 读取many和one的信息并装配query方法
	 */
	private void relyRead(List<Element> es, List<FinderData> rely, String flag) throws FinderException {
		if(es == null || es.size() == 0) {
			return;
		}
		
		for (Element e: es) {
			String entity = e.attributeValue(entity_);
			String key = e.attributeValue(mapping_key_);
			String type = null;
			
			//验证mapping-key合法性并获得key的Java类型
			if(StringUtil.isNull(key)) {
				throw new FinderException("many或者one标签的mapping-key属性未定义或其值为空", holder.getException());
			}else {
				Node n = e.selectSingleNode("/build-mapping/entity[@name='" + entity + "']/id[@name='" + key + "']");
				if(n == null) {
					n = e.selectSingleNode("/build-mapping/entity[@name='" + entity + "']/property[@name='" + key + "']");
				}
				if(n == null) {
					throw new FinderException("many或者one标签的mapping-key属性值非法:" + key, holder.getException());
				}else {
					type = n.valueOf("@type");
				}
			}
			
			FinderData data = new FinderData();
			//装配数据
			data.setMethod("query" + entity + "By" + StringUtil.firstUpper(key));
			data.setParams(type + " " + key);
			
			List<String> params = new ArrayList<String>();
			params.add(setterHQL(key, type));
			data.setParamSetter(params);
			
			if("many".equals(flag)) {
				data.setReturnType("List<" + entity + ">");
				data.setWarning(true);
			}else if("one".equals(flag)) {
				data.setReturnType(entity);
				data.setConvert(true);
				data.setOnly(true);
			}
			//导入bean对象
			holder.getDaoImpt().add(holder.getEntity().getBeanPackage() + "." + entity);
			
			//hql语句
			data.setState("from " + entity + " where " + key + "=:" + key);
			
			rely.add(data);
		}
	}
}
